/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 * C:\Program Files (x86)\City of Heroes>cityofheroes.exe -demoplay test3
 */

package org.homullus;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.nio.IntBuffer;
import java.util.concurrent.TimeoutException;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import org.lwjgl.util.glu.Cylinder;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.glu.Sphere;
import org.lwjgl.util.vector.Vector3f;
import org.homullus.SkeletonTransforms.ISkeletonTransform;
import org.homullus.Cube;


/**
 *
 * @author Gary
 */
public class EditorCanvas extends AWTGLCanvas implements Runnable
{
    Skeleton skeleton = null;
    public void SetSkeleton(Skeleton s) { skeleton = s;}
    public Skeleton GetSkeleton() { return skeleton; }

    private int dx = 0;
    private int dy = 0;
    private float zoom  = 1;
    private float tx = 0;
    private float ty = 0;
    private float rotx = 0;
    private float roty = 0;
    private boolean altDown = false;
    private boolean ctrlDown = false;
    private boolean wireframe = true;

    public EditorCanvas() throws LWJGLException
    {
        super();
        setPreferredSize(new Dimension(600,600));
        setBackground(Color.black);

        addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == e.BUTTON1)
                {
                    System.out.println("X:" + Integer.toString(e.getX()) + " Y:" + Integer.toString(e.getY()) );
                }
                super.mouseClicked(e);
            }
            @Override
            public void mousePressed(MouseEvent e) {
                dx = e.getX();
                dy = e.getY();
                super.mousePressed(e);
            }
        });

        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (altDown)
                {
                    tx += dx - e.getX(); // this needs to work this way to translate canvas cordinates to opengl coordinates
                    ty += e.getY() - dy;
                }
                else if (ctrlDown)
                {
                    roty += e.getX() - dx; // rotate around the y axis when movine left and right
                    rotx += e.getY() - dy; // rotate around the x axis when moing up and down
                }
                dx = e.getX();
                dy = e.getY();

                super.mouseDragged(e);
            }
        });

        addMouseWheelListener(new MouseWheelListener() {
            public void mouseWheelMoved(MouseWheelEvent e) {
                int scrollAmount = e.getUnitsToScroll();
                zoom += scrollAmount;
            }
        });

        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {

                if (e.isAltDown())
                {
                    altDown = true;
                }
                else if (e.isControlDown())
                {
                    ctrlDown = true;
                }
                super.keyPressed(e);
            }

            @Override
            public void keyReleased(KeyEvent e)
            {
                if (!e.isAltDown())
                {
                    altDown = false;
                }
                if (!e.isControlDown())
                {
                    ctrlDown = false;
                }
            }
        });

    }

    @Override
    protected void initGL() {
        super.initGL();
    }

    @Override
    public void update(Graphics g) {
        super.update(g);
    }

    public void ApplySkeletonTransform(ISkeletonTransform t)
    {
        if (skeleton != null)
            t.Transform(skeleton);
    }

    public void toggleWireframe()
    {
        wireframe = !wireframe;
    }

    public void setViewRotation(float x, float y)
    {
        rotx = x;
        roty = y;
    }

    @Override
    public void componentResized(ComponentEvent e) {
        super.componentResized(e);
    }

    @Override
    protected void paintGL() {
        super.paintGL();
        try
        {

            //set up the projection
            GL11.glViewport(0,0,getWidth(),getHeight());
            GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glLoadIdentity();
            GLU.gluPerspective(45, getWidth()/getHeight(), 1.0f, 1000.0f);

            //Draw the scene
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glLoadIdentity();
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);

            GLU.gluLookAt(0, 0, 100, 0, 0, 0, 0, 1, 0);

            GL11.glTranslatef(0,0,-zoom);
            GL11.glTranslatef(tx, ty, 0);
            GL11.glRotatef(rotx, 1, 0, 0);
            GL11.glRotatef(roty, 0, 1, 0);

            GL11.glBegin(GL11.GL_LINES);
            //xaxis
            GL11.glColor3f(1, 0, 0);
            GL11.glVertex3f(0, 0, 0);
            GL11.glVertex3f(25, 0, 0);

            //yaxis
            GL11.glColor3f(0, 1, 0);
            GL11.glVertex3f(0, 0, 0);
            GL11.glVertex3f(0, 25, 0);

            //zaxis
            GL11.glColor3f(0, 0, 1);
            GL11.glVertex3f(0, 0, 0);
            GL11.glVertex3f(0, 0, 25);

            GL11.glEnd();

            GL11.glPushMatrix();

            if (skeleton != null)
                skeleton.Draw(wireframe);

            GL11.glPopMatrix();

            swapBuffers();
        }
        catch (LWJGLException e)
        {
            System.err.print("Error painting GL canvas");
        }
        
        
    }

    public void run() {
        while(true)
        {
            //System.out.println("updating");
            repaint();
            try { Thread.sleep(33); }
            catch (InterruptedException e) {}
        }
    }

    
}
